<script setup>
import { ref, computed, onMounted, onUnmounted } from 'vue'
import SvgIcon from '@/components/icon/SvgIcon.vue'
import HelpTooltip from './components/HelpTooltip.vue'
import { deviceList } from './config/devices'
import { usePlacing } from './composables/usePlacing'
import { useCanvas } from './composables/useCanvas'
import { useCanvasPersist } from './composables/useCanvasPersist'
import { useTooltip, TooltipPosition } from './composables/useTooltip'
import { useDrawing } from './composables/useDrawing'
import DeviceSelectionDialog from './components/DeviceSelectionDialog.vue';
import CanvasInfo from './components/CanvasInfo.vue';
const deviceDialogVisible = ref(false)
const isDrawingLine = ref(false)
const isPlacing = ref(false)
const placingType = ref(null)
const selectedDeviceType = ref("all") // 当前选中的设备类型筛选
const isEdit = ref(true)
const canvasRef = ref(null)
let canvas = null
let startPlacing = null
let exitPlacingMode = null
let canvasContainer = ref(null)
let saveWithConfirm = null
let loadFromLocal = null
let cancelEdit = null
const props = defineProps(['spaceInfo']);
// 筛选选项
const filterOptions = computed(() => {
    return [
        { label: '全部', value: "all" },
        ...deviceList.map(device => ({
            label: device.label,
            value: device.name
        }))
    ]
})

// 筛选设备的方法
const filterCanvasDevices = (type) => {
    if (!canvas) return
    if (type === "all") {
        canvas.getObjects().forEach(obj => {
            obj.visible = true
        })
        canvas.requestRenderAll()
        return
    }
    selectedDeviceType.value = type
    const objects = canvas.getObjects()
    console.log(objects);

    objects.forEach(obj => {
        if (obj.deviceInfo && obj.deviceInfo.type === type) {
            obj.visible = true
        } else {
            obj.visible = false
        }
    })

    canvas.requestRenderAll()
}

// 清空筛选
const clearDeviceFilter = () => {
    filterCanvasDevices("all")
}

// 初始化 tooltip
const { initTooltipEvents } = useTooltip(canvasRef, {
    defaultPosition: TooltipPosition.BOTTOM,
})

const showDeviceDialog = () => {
    deviceDialogVisible.value = true
}

const handleSelectDevice = (subDevice) => {
    console.log(subDevice);
    console.log(deviceList);

    const parentDevice = deviceList.find(d => d.name === subDevice.type);

    if (parentDevice) {
        startPlacing('device', {
            ...parentDevice,
            subDevice: subDevice,
            deviceType: parentDevice.name // 添加设备类型标记
        });
    }
};

const startAddingRect = () => {
    startPlacing('rect')
}

const startAddingCircle = () => {
    startPlacing('circle')
}

const startAddingText = () => {
    startPlacing('text')
}

const deleteSelected = () => {
    const activeObject = canvas.getActiveObject()
    if (activeObject) {
        canvas.remove(activeObject)
        canvas.requestRenderAll()
    }
}
const clearCanvas = () => {
    canvas.clear()
    canvas.backgroundColor = '#fff'
    canvas.requestRenderAll()
}

const handleKeyDown = (e) => {
    const activeObject = canvas.getActiveObject()
    const isEditingText = activeObject && activeObject.isEditing

    if ((e.key === 'Delete' || e.key === 'Backspace') && !isEditingText) {
        deleteSelected()
    }

    if (e.key === 'Escape' && isPlacing.value) {
        exitPlacingMode()
    }
}

const save = async () => {
    let res = saveWithConfirm()
    if (res) {
        isEdit.value = false
    }
}

let toggleLineDrawing = null

// 画布信息相关的状态
const canvasInfo = ref({
    zoom: 1,
    width: 0,
    height: 0,
    viewportLeft: 0,
    viewportTop: 0
})

// 更新画布信息的函数
const updateCanvasInfo = () => {
    if (canvas) {
        canvasInfo.value = {
            zoom: Math.round(canvas.getZoom() * 100) / 100,
            width: Math.round(canvas.width),
            height: Math.round(canvas.height),
            viewportLeft: Math.round(canvas.viewportTransform[4]),
            viewportTop: Math.round(canvas.viewportTransform[5])
        }
    }
}

// 显示画布信息的开关
const showCanvasInfo = ref(false)

// 控制画布信息显示
const toggleCanvasInfo = () => {
    showCanvasInfo.value = !showCanvasInfo.value
}

const resizeDialogVisible = ref(false)
const resizeMode = ref('fit')
const customSize = ref({
    width: 800,
    height: 600
})

const showResizeDialog = () => {
    if (canvas) {
        customSize.value.width = canvasInfo.value.width
        customSize.value.height = canvasInfo.value.height
    }
    resizeDialogVisible.value = true
}

const handleResize = () => {
    if (!canvas) return

    if (resizeMode.value === 'fit') {
        const container = canvasContainer.value
        const width = container.clientWidth
        const height = container.clientHeight

        canvas.setWidth(width)
        canvas.setHeight(height)
    } else {
        canvas.setWidth(customSize.value.width)
        canvas.setHeight(customSize.value.height)
    }

    canvas.requestRenderAll()
    updateCanvasInfo()
    resizeDialogVisible.value = false
    ElMessage.success('画布大小已更新')
}

onMounted(() => {
    const container = canvasRef.value.parentElement
    const width = container.clientWidth
    const height = container.clientHeight
    canvas = new fabric.Canvas(canvasRef.value, {
        width: width,
        height: height,
        backgroundColor: '#fff',
        isDrawingMode: false
    })

    // 初始化画布持久化功能
    const persistMethods = useCanvasPersist(canvas)
    saveWithConfirm = persistMethods.saveWithConfirm
    loadFromLocal = persistMethods.loadFromLocal
    cancelEdit = async () => {
        await persistMethods.cancelEdit()
        isEdit.value = false
    }

    const { performPlacement, startPlacing: _startPlacing, exitPlacingMode: _exitPlacingMode } = usePlacing(canvas)
    startPlacing = _startPlacing
    exitPlacingMode = _exitPlacingMode

    // 初始化提示框事件
    initTooltipEvents(canvas)
    const { toggleLineDrawing: _toggleLineDrawing, startDrawingLine, drawLine, finishDrawingLine } = useDrawing(canvas)
    toggleLineDrawing = _toggleLineDrawing

    // 处理画布点击事件
    const handleCanvasClick = (e) => {
        const pointer = canvas.getPointer(e.e)
        performPlacement(pointer)
    }

    const { handleWheel, handleMouseDown, handleMouseMove, handleMouseUp } = useCanvas(canvas)

    // 添加画布事件监听器
    canvas.on('mouse:wheel', handleWheel)
    canvas.on('mouse:down', handleMouseDown)
    canvas.on('mouse:move', handleMouseMove)
    canvas.on('mouse:up', handleMouseUp)
    canvas.on('mouse:dblclick', (options) => {
        if (options.target && (options.target instanceof fabric.IText)) {
            options.target.enterEditing()
            options.target.selectAll()
            canvas.requestRenderAll()
        }
    })
    canvas.on('mouse:down', startDrawingLine)
    canvas.on('mouse:move', drawLine)
    canvas.on('mouse:up', finishDrawingLine)
    canvas.on('mouse:down', handleCanvasClick)
    canvas.on('after:render', updateCanvasInfo)
    updateCanvasInfo()
    document.addEventListener('keydown', handleKeyDown)// 初始加载保存的数据
    persistMethods.loadFromLocal()
    // 启动自动保存
    persistMethods.startAutoSave()
})

onUnmounted(() => {
    document.removeEventListener('keydown', handleKeyDown)
    canvas.off('mouse:wheel', handleWheel)
    canvas.off('mouse:down', handleMouseDown)
    canvas.off('mouse:move', handleMouseMove)
    canvas.off('mouse:up', handleMouseUp)
    canvas.off('mouse:down', startDrawingLine)
    canvas.off('mouse:move', drawLine)
    canvas.off('mouse:up', finishDrawingLine)
    canvas.dispose()
    if (canvas) {
        canvas.off('after:render', updateCanvasInfo)
    }
    persistMethods.stopAutoSave()
})
</script>

<template>
    <div class="device-canvas-container">
        <div class="canvas-card">
            <div class="canvas-area" ref="canvasContainer">
                <!-- 添加筛选控件 -->
                <div class="filter-controls">
                    <div class="space-name">{{ spaceInfo.name }}</div>
                    <el-select size="small" v-model="selectedDeviceType" placeholder="筛选设备类型"
                        @change="filterCanvasDevices" clearable @clear="clearDeviceFilter">
                        <el-option v-for="option in filterOptions" :key="option.value" :label="option.label"
                            :value="option.value" />
                    </el-select>
                    <HelpTooltip />

                </div>

                <div class="top-buttons" v-if="isEdit">
                    <el-button type="primary" size="small" @click="save">保存</el-button>
                    <el-button size="small" @click="cancelEdit">取消</el-button>
                </div>
                <div class="top-buttons" v-if="!isEdit">
                    <el-button type="primary" size="small" @click="isEdit = true">编辑</el-button>
                </div>
                <canvas ref="canvasRef"></canvas>
                <CanvasInfo :canvasInfo="canvasInfo" :visible="showCanvasInfo" />
            </div>

            <div class="bottom-toolbar">
                <div v-if="isEdit" class="tool-buttons">
                    <el-tooltip content="添加设备" placement="top" effect="light">
                        <div class="tool-button" :class="{ 'active': isPlacing && placingType === 'device' }"
                            @click="showDeviceDialog">
                            <SvgIcon icon="device-draw" size="24px" />
                        </div>
                    </el-tooltip>

                    <el-tooltip content="添加矩形" placement="top" effect="light">
                        <div class="tool-button" :class="{ 'active': isPlacing && placingType === 'rect' }"
                            @click="startAddingRect">
                            <SvgIcon icon="square" size="24px" />
                        </div>
                    </el-tooltip>

                    <el-tooltip content="添加圆形" placement="top" effect="light">
                        <div class="tool-button" :class="{ 'active': isPlacing && placingType === 'circle' }"
                            @click="startAddingCircle">
                            <SvgIcon icon="circle" size="24px" />
                        </div>
                    </el-tooltip>

                    <el-tooltip content="绘制线条" placement="top" effect="light">
                        <div class="tool-button" :class="{ 'active': isDrawingLine }" @click="toggleLineDrawing">
                            <SvgIcon icon="line" size="24px" />
                        </div>
                    </el-tooltip>

                    <el-tooltip content="添加文字" placement="top" effect="light">
                        <div class="tool-button" :class="{ 'active': isPlacing && placingType === 'text' }"
                            @click="startAddingText">
                            <SvgIcon icon="text" size="24px" />
                        </div>
                    </el-tooltip>

                    <el-tooltip content="删除选中" placement="top" effect="light">
                        <div class="tool-button" @click="deleteSelected">
                            <i class="fa fa-trash"></i>
                        </div>
                    </el-tooltip>

                    <el-tooltip content="清空画布" placement="top" effect="light">
                        <div class="tool-button" @click="clearCanvas">
                            <i class="fa fa-refresh"></i>
                        </div>
                    </el-tooltip>

                    <el-tooltip content="画布信息" placement="top" effect="light">
                        <div class="tool-button" :class="{ 'active': showCanvasInfo }" @click="toggleCanvasInfo">
                            <i class="fa fa-info-circle"></i>
                        </div>
                    </el-tooltip>

                    <el-tooltip content="调整画布大小" placement="top" effect="light">
                        <div class="tool-button" @click="showResizeDialog">
                            <i class="fa fa-arrows-alt"></i>
                        </div>
                    </el-tooltip>
                </div>

                <div v-if="!isEdit" class="tool-buttons">
                    <el-tooltip content="控制设备" placement="top" effect="light">
                        <div class="tool-button" style="width: 80px;" @click="isEdit = true">
                            <SvgIcon icon="operate" size="24px" />
                        </div>
                    </el-tooltip>
                </div>
            </div>
        </div>

        <device-selection-dialog :visible="deviceDialogVisible" :device-list="deviceList"
            @update:visible="deviceDialogVisible = $event" @select-device="handleSelectDevice" />

        <el-dialog v-model="resizeDialogVisible" title="调整画布大小" width="400px" :close-on-click-modal="false">
            <div class="resize-options">
                <el-radio-group v-model="resizeMode" class="resize-mode-group">
                    <el-radio value="fit" label="适应屏幕">适应屏幕</el-radio>
                    <el-radio value="custom" label="自定义大小">自定义大小</el-radio>
                </el-radio-group>

                <div v-if="resizeMode === 'custom'" class="custom-size-inputs">
                    <el-form :model="customSize" label-width="80px">
                        <el-form-item label="宽度">
                            <el-input-number v-model="customSize.width" :min="100" :max="5000" placeholder="请输入宽度" />
                        </el-form-item>
                        <el-form-item label="高度">
                            <el-input-number v-model="customSize.height" :min="100" :max="5000" placeholder="请输入高度" />
                        </el-form-item>
                    </el-form>
                </div>
            </div>
            <template #footer>
                <span class="dialog-footer">
                    <el-button @click="resizeDialogVisible = false">取消</el-button>
                    <el-button type="primary" @click="handleResize">确定</el-button>
                </span>
            </template>
        </el-dialog>
    </div>
</template>

<style scoped>
.device-canvas-container {
    width: 100%;
    height: 100%;
    box-sizing: border-box;
}

.canvas-card {
    height: 100%;
    display: flex;
    flex-direction: column;
}

.filter-controls {
    position: absolute;
    top: var(--gap-normal);
    left: var(--gap-normal);
    z-index: 1000;
    display: flex;
    align-items: center;
    gap: var(--gap-small);
}

.space-name {
    font-size: var(--font-size-normal);
    color: var(--text-color-primary);
}

/* 设备筛选下拉框样式 */
.filter-controls :deep(.el-select) {
    width: 150px;
}

.canvas-status {
    position: absolute;
    bottom: 10px;
    left: 10px;
    background-color: rgba(0, 0, 0, 0.6);
    padding: 8px 12px;
    border-radius: 4px;
    color: white;
    font-size: 12px;
    display: flex;
    gap: 16px;
    z-index: 1000;
}

.status-item {
    display: flex;
    align-items: center;
    gap: 4px;
}

.canvas-area {
    position: relative;
    flex: 1;
    height: 100%;
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: #ccc;
    overflow: hidden;
}

.label {
    color: rgba(255, 255, 255, 0.8);
}

.value {
    font-family: monospace;
}

.top-buttons {
    position: absolute;
    top: var(--gap-normal);
    right: var(--gap-normal);
    display: flex;
    gap: var(--gap-small);
    z-index: 1000;
}

.bottom-toolbar {
    height: 60px;
    margin-bottom: var(--gap-normal);
    display: flex;
    align-items: center;
    justify-content: center;
}

.tool-buttons {
    display: flex;
    gap: var(--gap-small);
}

.tool-button {
    width: 42px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    border-radius: 4px;
    transition: all 0.3s;
}

.tool-button:hover {
    box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.25);
}

.tool-button.active {
    box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.25);
    background-color: var(--el-color-primary-light-8);
}

.fa {
    font-size: 24px;
}

.device-selection {
    display: flex;
    min-height: 400px;
}

.device-wrapper {
    display: flex;
    flex: 1;
}

.device-category {
    width: 200px;
    border-right: 1px solid var(--el-border-color);
    padding: var(--gap-normal);
    overflow-y: auto;
}

.device-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: var(--gap-small);
    border: 1px solid var(--el-border-color);
    border-radius: var(--el-border-radius-base);
    cursor: pointer;
    margin-bottom: var(--gap-small);
    transition: all 0.3s;
}

.device-item:hover {
    border-color: var(--el-color-primary);
    background-color: var(--el-color-primary-light-9);
}

.device-item.active {
    background-color: var(--el-color-primary-light-8);
    border-color: var(--el-color-primary);
}

.device-list {
    flex: 1;
    padding: var(--gap-normal);
    overflow-y: auto;
}

.sub-device-item {
    padding: var(--gap-small) var(--gap-normal);
    border: 1px solid var(--el-border-color);
    border-radius: var(--el-border-radius-base);
    margin-bottom: var(--gap-small);
    cursor: pointer;
    transition: all 0.3s;
}

.sub-device-item:hover {
    background-color: var(--el-color-primary-light-9);
    border-color: var(--el-color-primary);
}

.device-name {
    margin-top: var(--gap-small);
    font-size: var(--el-font-size-small);
    color: var(--el-text-color-regular);
}

canvas {
    border: 1px solid var(--el-border-color);
    background-color: white;
}

.resize-options {
    padding: var(--gap-normal);
}

.resize-mode-group {
    margin-bottom: var(--gap-normal);
}

.custom-size-inputs {
    margin-top: var(--gap-normal);
}
</style>